﻿using System;
using System.Collections.Generic;
using System.Linq;

namespace IRC
{
    interface IIrcCommandHandler
    {
        void HandleMessage(IrcMessage message);
    }

    internal class DefaultIrcCommandHandler : IIrcCommandHandler
    {
        public void HandleMessage(IrcMessage message)
        {
            Console.WriteLine(String.Format("cmd[{0}] ", message.Command) + String.Join(" ", message.Params.ToArray()));
        }
    }

    internal class JoinIrcCommandHandler : IIrcCommandHandler
    {
        private readonly Dictionary<string, Channel> _channels;

        public JoinIrcCommandHandler(Dictionary<string, Channel> channels)
        {
            _channels = channels;
        }

        public void HandleMessage(IrcMessage message)
        {
            //Console.WriteLine(String.Format("join: ", message.Command) + String.Join(" ", message.Params.ToArray()));
            var channelName = message.Params[0];
            var userName = message.Params[1];

            if(!_channels.ContainsKey(channelName))
                throw new Exception("Received JOIN from server for channel we do not posses.");

            if (_channels[channelName].Users.Contains(userName))
                throw new Exception("We received a JOIN from server for a user that is already in the channel.");

            _channels[channelName].Users.Add(userName);
        }
    }

    public class IrcCommandProcessor
    {
        private readonly Dictionary<string, IIrcCommandHandler> _handlers;
        private readonly Dictionary<string, Channel> _channels;

        public IrcCommandProcessor(Dictionary<string, Channel> channels)
        {
            _channels = channels;
            _handlers = new Dictionary<string, IIrcCommandHandler>
            {
                {"default", new DefaultIrcCommandHandler()}, 
                {"JOIN", new JoinIrcCommandHandler(_channels)}
            };

            //TODO: replace with "automatic" discovery of handlers
        }

        public void ProcessMessage(IrcMessage message)
        {
            if(_handlers.ContainsKey(message.Command.ToUpperInvariant()))
                _handlers[message.Command].HandleMessage(message);
            else
                _handlers["default"].HandleMessage(message);
        }
    }
}
